﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.IO;
using System.Collections;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;

namespace PO_2011.Noise
{
    class Noise
    {
        private static int[,] maskx;

        private static String mask_type;

        //ile jest okolicznych piksel, np. maska size 3, ma z kazdej strony 1 piksel, maska 9, ma 4 z kazdej strony
        private static int minus;

        private static int[,] checkboxes;

        public static Bitmap create(Bitmap image, String maskType, int mask_size, int[,] checkbox)
        {
            mask_type = maskType;

            checkboxes = checkbox;

            createMask(ref mask_size);

            minus = (int) (mask_size / 2);


            if (mask_type == "erozja")
            {
                makeNoise(ref image, ref mask_size, (byte)0, (byte)255);
            }
            else if(mask_type == "dylacja")
            {
                makeNoise(ref image, ref mask_size, (byte)255, (byte)0);
            }

            return image;
        }


        private static void createMask(ref int mask_size)
        {
            maskx = new int[mask_size, mask_size];

            switch (mask_type)
            {
                case "erozja":
                case "dylacja":
                    if (mask_size == 3)
                    {
                        maskx = new int[3, 3] { { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 } };
                    }
                    else if(mask_size == 5)
                    {
                        maskx = new int[5, 5] { { 1, 1, 1, 1, 1 }, { 1, 1, 1, 1, 1 }, { 1, 1, 1, 1, 1 }, { 1, 1, 1, 1, 1 }, { 1, 1, 1, 1, 1 } };
                    }
                    break;
                default:
                    break;
            }

            if (checkboxes != null)
            {
                maskx = checkboxes;
            }

        }

        private static void makeNoise(ref Bitmap image, ref  int mask_size, byte one, byte two)
        {
            BitmapData bData = image.LockBits(new Rectangle(new Point(), image.Size), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);

            int byteCount = 3 * image.Width * image.Height;
            byte[] bitmapData = new byte[byteCount];

            Marshal.Copy(bData.Scan0, bitmapData, 0, byteCount);
            image.UnlockBits(bData);

            byte[] bitmapDataNoise = new byte[bitmapData.Length];

            int index = 0;
            bool breaker = false;

            Byte color;

            for (int x = 0; x < bitmapData.Length; x++)
            {
                index = x;
                // pierwszy rzad, lewy rzad, prawy rzad, dolny rzad
                if ((index < (3 * image.Width)) || ((index % (3 * image.Width) == 0) || (index % (3 * image.Width) == 1) || (index % (3 * image.Width) == 2)) || ((index % (3 * image.Width) == (3 * image.Width) - 3) || (index % (3 * image.Width) == (3 * image.Width) - 2) || (index % image.Width == (3 * image.Width) - 1)) || (x >= (bitmapData.Length - 6 * image.Width)))
                {
                    bitmapDataNoise[index] = (byte) two;
                    continue;
                }

                for (int i = 0; i < mask_size; i++)
                {
                    if(breaker) break;

                    for (int j = 0; j < mask_size; j++)
                    {
                        index = x - (i - 1) * 3 * image.Width +  3 * (j - 1);

                        if (0 < index && index < bitmapData.Length && index != x && maskx[i, j] > 0)
                        {
                            color = bitmapData[index];
                            if ((char)color == two)
                            {
                                bitmapDataNoise[x] = (byte) two;
                                breaker = true;
                                break;
                            }
                        }
                    }
                }
                if (!breaker)
                {
                    bitmapDataNoise[x] = (byte) one;
                }
                breaker = false;
            }

            
            BitmapData bd = image.LockBits(new Rectangle(0, 0, image.Width, image.Height) , ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
            Marshal.Copy(bitmapDataNoise, 0, bd.Scan0, bitmapDataNoise.Length);
            image.UnlockBits(bd);
        }

    }
}
